package com.fy.service.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.fy.common.constant.Constants;
import com.fy.common.constant.RedisKeyConstant;
import com.fy.common.entity.SkImGroup;
import com.fy.common.entity.SkImGroupMember;
import com.fy.common.model.im.MessageModel;
import com.fy.common.model.im.UserOnlineStatus;
import com.fy.dao.mapper.SkImGroupMemberMapper;
import com.fy.framework.component.config.TenantContextHolder;
import com.fy.service.service.ImBrokerGroupService;
import com.fy.service.service.ImBrokerService;

import java.util.concurrent.TimeUnit;

import com.fy.service.service.SkImGroupMemberService;
import com.fy.service.service.SkImGroupService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RBatch;
import org.redisson.api.RBucket;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ImBrokerGroupServiceImpl implements ImBrokerGroupService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private RocketMQTemplate rocketMQTemplate;

    private RedissonClient redisson;

    private ImBrokerService imBrokerService;

    private SkImGroupMemberService skImGroupMemberService;

    private SkImGroupService skImGroupService;

    @Autowired
    public void setRocketMQTemplate(RocketMQTemplate rocketMQTemplate) {
        this.rocketMQTemplate = rocketMQTemplate;
    }
    @Autowired
    public void setRedisson(RedissonClient redisson) {
        this.redisson = redisson;
    }
    @Autowired
    public void setImBrokerService(ImBrokerService imBrokerService) {
        this.imBrokerService = imBrokerService;
    }
    @Autowired
    public void setSkImGroupMemberService(SkImGroupMemberService skImGroupMemberService) {
        this.skImGroupMemberService = skImGroupMemberService;
    }
    @Autowired
    public void setSkImGroupService(SkImGroupService skImGroupService) {
        this.skImGroupService = skImGroupService;
    }

    @Override
    public void sendGroupMessage(MessageModel messageModel, Boolean isUpdateSession) {
        //获取群信息 做禁言等权限验证
        //SkImGroup group = this.getGroup(messageModel);

        //从缓存查询  获取所有群成员id
        RMapCache<Long, JSONObject> groupMembers = redisson.getMapCache(messageModel.getTenantId() + "|" + RedisKeyConstant.GROUP_MEMBERS + messageModel.getToGroup());
        //获取在线的群成员设备
        List<UserOnlineStatus> onlineDevice = this.getGroupMembersOnlineDevice(messageModel,groupMembers);
        if (isUpdateSession) {
            /*//修改自己的会话
            imBrokerService.updateFromSessionLastMessage(messageModel, null);*/
            //修改群成员会话
            for (Long aLong : groupMembers.keySet()) {
                messageModel.setTo(aLong);
               imBrokerService.updateToSessionLastMessage(messageModel,null);
            }
        }
        //下发消息 只下发在线成员
        for (UserOnlineStatus onlineStatus : onlineDevice) {
            rocketMQTemplate.convertAndSend(onlineStatus.getLastOnlineHost().replace(".", "_").replace(":", "_"), JSONObject.toJSONString(messageModel));
        }

    }

    @Override
    public List<UserOnlineStatus> getGroupMembersOnlineDevice(MessageModel messageModel, RMapCache<Long, JSONObject> groupMembers) {
        TenantContextHolder.setTenant(messageModel.getTenantId());
       List<UserOnlineStatus> membersDevice = new ArrayList<>();
        if (groupMembers != null && groupMembers.size() != 0) {
            for (Long deviceCode : groupMembers.keySet()) {
                JSONObject memberObj =  groupMembers.get(deviceCode);
                UserOnlineStatus onlineStatus = JSONObject.toJavaObject(memberObj,UserOnlineStatus.class);
                if(onlineStatus.getIsOnline() == Constants.YES){
                    membersDevice.add(onlineStatus);
                }
            }
        } else {
            //没有群成员缓存的情况
            List<SkImGroupMember> members = skImGroupMemberService.selectList(new EntityWrapper<SkImGroupMember>().eq("sk_im_group_id", messageModel.getToGroup()));
            if (members == null) throw new RuntimeException("找不到群成员信息");
            for (SkImGroupMember member : members) {
                //获取用户在线情况 加入到群缓存
                List<UserOnlineStatus> onlineDeviceList = imBrokerService.getOnlineDevice(messageModel.getTenantId(),member.getSkImUserId());
                for (UserOnlineStatus onlineStatus : onlineDeviceList) {
                    membersDevice.add(onlineStatus);
                }
            }
            groupMembers.expire(86400, TimeUnit.SECONDS);
        }
        return membersDevice;
    }

    @Override
    public SkImGroup getGroup(MessageModel messageModel) {
        TenantContextHolder.setTenant(messageModel.getTenantId());
        RBucket<SkImGroup> group = redisson.getBucket(RedisKeyConstant.GROUP_INFO + messageModel.getToGroup());

        if (group.isExists() ) {
            return group.get();
        } else {
            SkImGroup skImGroup = skImGroupService.selectOne(new EntityWrapper<SkImGroup>().eq("id", messageModel.getToGroup()));
            group.set(skImGroup);
            group.expire(86400, TimeUnit.SECONDS);
            return skImGroupService.selectOne(new EntityWrapper<SkImGroup>().eq("id", messageModel.getToGroup()));
        }


    }
}
